package czh.cocoa.ui.impl;

import czh.cocoa.foundation.NSString;
import czh.cocoa.graphics.CGColor;
import czh.cocoa.graphics.CGContext;
import czh.cocoa.graphics.CGPoint;
import czh.cocoa.graphics.CGRect;
import czh.cocoa.graphics.CGSize;
import czh.cocoa.ui.UIColor;
import czh.cocoa.ui.UIFont;
import czh.cocoa.ui.UILineBreakMode;
import czh.cocoa.ui.UITextAlignment;
import czh.cocoa.ui.UIView;

import static czh.cocoa.ui.UIKit.*;
import static czh.cocoa.graphics.CGContext.*;

public class UILabel extends UIView {

	private NSString mText;
	
	private UITextAlignment mTextAlign;
	
	private UIFont mFont;
	
	private float mMinFontSize;
	
	private boolean mAdjustsFontSizeToFitWidth;
	
	private int mNumberOfLines;
	
	private UILineBreakMode mLineBreakMode;
	
	private UIColor mTextColor;
	
	private boolean mHighlighted;
	
	private UIColor mHighlightedTextColor;
	
	public UILabel() {
		
	}

	public UILabel(CGRect frame) {
		super(frame);
	}
	
	protected void init() {
		super.init();
		mTextAlign = UITextAlignment.Left;
		mLineBreakMode = UILineBreakMode.TailTruncation;
		mNumberOfLines = 1;
		mTextColor = UIColor.blackColor();
		mHighlightedTextColor = UIColor.whiteColor();
		mFont = UIFont.systemFontOfSize(18);
		setUserInteractionEnabled(false);
		setContentMode(UIViewContentModeRedraw);
		setClipsToBounds(true);
	}
	
	public void setText(NSString text) {
		mText = text;
		setNeedsDisplay();
	}
	
	public NSString text() {  
		return mText;
	}
	
	public void setTextColor(UIColor color) {
		mTextColor = color;
		if (!mHighlighted) {
			setNeedsDisplay();
		}
	}
	
	public UIColor textColor() {
		return mTextColor;
	}
	
	public void setHighlightedTextColor(UIColor color) {
		mHighlightedTextColor = color;
		if (mHighlighted) { 
			setNeedsDisplay();
		}
	}
	
	public UIColor highlightedTextColor() {
		return mHighlightedTextColor;
	}
	
	public void setHighlighted(boolean highlighted) {
		if (mHighlighted != highlighted) {
			mHighlighted = highlighted;
			setNeedsDisplay();
		}
	}
	
	public boolean isHighlighted() {
		return mHighlighted;
	}
	
	public void setTextAlignment(UITextAlignment align) {
		mTextAlign = align;
		setNeedsDisplay();
	}
	
	public UITextAlignment textAlignment() {
		return mTextAlign;
	}
	
	public void setFont(UIFont font) {
		mFont = font;
		setNeedsDisplay();
	}
	
	public UIFont font() {
		return mFont;
	}
	
	public void setMinimumFontSize(float fontSize) {
		mMinFontSize = fontSize;
	}
	
	public float minimumFontSize() {
		return mMinFontSize;
	}
	
	public void setAdjustsFontSizeToFitWidth(boolean adjusts) {
		mAdjustsFontSizeToFitWidth = adjusts;
	}
	
	public boolean adjustsFontSizeToFitWidth() {
		return mAdjustsFontSizeToFitWidth;
	}
	
	public void setNumberOfLines(int lines) {
		mNumberOfLines = lines;
	}
	
	public int numberOfLines() {
		return mNumberOfLines;
	}
	
	public void setLineBreakMode(UILineBreakMode lineBreakMode) {
		mLineBreakMode = lineBreakMode;
	}
	
	public UILineBreakMode lineBreakMode() {
		return mLineBreakMode;
	}
	
	public void drawRect(CGRect rect) {
		if (mText != null) {
			
			CGContext ctx = UIGraphicsGetCurrentContext();
			UIColor color = mHighlighted ? mHighlightedTextColor : mTextColor;
			CGContextSetFillColorWithColor(ctx, color.CGColor());
			
			CGRect frame = frame();
			
			if (mNumberOfLines == 1) {
				
				if(mAdjustsFontSizeToFitWidth) {
					
					float[] actualFontSize = new float[1];
					CGSize size = mText.sizeWithFontMinFontSizeActualFontSizeForWidthLineBreakMode(mFont, mMinFontSize, 
							actualFontSize, frame.size.width, mLineBreakMode);
					CGPoint position = calculateTextPosition(size);
					UIFont actual_font = mFont.fontWithSize(actualFontSize[0]);
					mText.drawAtPointForWidthWithFontLineBreakMode(position, frame.size.width, actual_font, mLineBreakMode);
					
				} else {
					
					CGSize size = mText.sizeWithFontForWidthLineBreakMode(mFont, frame.size.width, mLineBreakMode);
					CGPoint position = calculateTextPosition(size);
					mText.drawAtPointForWidthWithFontLineBreakMode(position, frame.size.width, mFont, mLineBreakMode);
					
				}
				
			} else {
				
				float lineh = mFont.ascender() - mFont.descender();
				float maxh = lineh * (mNumberOfLines > 1 ? mNumberOfLines : Integer.MAX_VALUE);
				maxh = Math.min(maxh, frame.size.height);
				
				CGSize constrained_size = CGSizeMake(frame.size.width, maxh);
				CGSize size = mText.sizeWithFontConstrainedToSizeLineBreakMode(mFont, constrained_size, mLineBreakMode);
				
				CGPoint position = calculateTextPosition(size);
				CGRect constrained_rect = CGRectMake(position.x, position.y, 
										constrained_size.width, constrained_size.height); 
				mText.drawInRectWithFontLineBreakMode(constrained_rect, mFont, mLineBreakMode);
				
			}
			
		}
	}
	
	private CGPoint calculateTextPosition(CGSize textSize) {
		
		CGRect frame = frame();
		
		switch (mTextAlign) {
		case Left: 
			return CGPointMake(0, (frame.size.height - textSize.height)/2);
		case Center:
			return CGPointMake((frame.size.width - textSize.width)/2, 
					(frame.size.height - textSize.height)/2);
		case Right:
		default:
			return CGPointMake(frame.size.width - textSize.width, 
					(frame.size.height - textSize.height)/2);
		}
		
	}
	
	public CGSize sizeThatFits(CGSize size) {
		if (mText == null) {
			return CGSizeMake(0, 0);
		}
		
		CGSize size2;
		
		if (mNumberOfLines == 1) {
			size2 = mText.sizeWithFontForWidthLineBreakMode(mFont, size.width, mLineBreakMode);
		} else {
			size2 = mText.sizeWithFontConstrainedToSizeLineBreakMode(mFont, size, mLineBreakMode);
		}
		
		size2.width += 2; //make text not clip when drawing
		return size2;
	}
	
}




